﻿using JESAI.Core.Util.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;

namespace JESAI.Core.Util.Collections
{

    /// <summary>
    /// 集合(<see cref="ICollection{T}"/>) 扩展
    /// </summary>
    public static partial class CollectionExtensions
    {
        /// <summary>
        /// 添加批量项。添加多个元素到集合中
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <param name="collection">集合</param>
        /// <param name="items">元素集合</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns>添加成功的元素数量</returns>
        public static int AddRange<T>(this ICollection<T> collection, IEnumerable<T> items)
        {
            if (collection == null)
                throw new ArgumentNullException(nameof(collection));
            if (items == null)
                throw new ArgumentNullException(nameof(items));
            var addedCount = 0;
            foreach (var item in items)
            {
                collection.Add(item);
                addedCount++;
            }

            return addedCount;
        }

        /// <summary>
        /// 将集合转换为树形结构的列表。将集合中的元素按照父子关系转换为树形结构的列表
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <param name="collection">集合</param>
        /// <returns>树形结构</returns>
        public static ICollection<T1> ToTreeList<T1, T2>(this ICollection<T1> collection, Func<T1, T2> parentIdFunc, Func<T1, T2> idFunc, Func<T1, ICollection<T1>> childrenFunc)
        {
            var rootNodes = new List<T1>();
            var childNodes = new List<T1>();
            foreach (var item in collection)
            {
                //if (parentIdFunc(item) == default(T2))

                var parentId = parentIdFunc(item);
                //如何判断parentId 等于空字符串
                var isDefault = EqualityComparer<T2>.Default.Equals(parentId, default(T2));
                if (typeof(T2) == typeof(string))
                {
                    var parentIdString = parentId as string;
                    isDefault = isDefault || string.IsNullOrEmpty(parentIdString);
                }
                if (isDefault)
                {
                    rootNodes.Add(item);
                }
                else
                {
                    childNodes.Add(item);
                }
            }
            foreach (var childNode in childNodes)
            {
                //var parentNode = collection.FirstOrDefault(p => idFunc(p) == parentIdFunc(childNode));
                var parentNode = collection.FirstOrDefault(p => EqualityComparer<T2>.Default.Equals(idFunc(p), parentIdFunc(childNode)));
                if (parentNode != null)
                {
                    var children = childrenFunc(parentNode);
                    if (children == null)
                    {
                        children = new List<T1>();
                        //设置childrenFunc的集合为新创建的集合
                        SetPropertyValue(parentNode, "Children", children);
                    }
                    children.Add(childNode);
                }
            }
            return rootNodes;
        }

        private static void SetPropertyValue(object obj, string propertyName, object value)
        {
            var propertyInfo = obj.GetType().GetProperty(propertyName);
            if (propertyInfo == null)
                throw new ArgumentException($"Property {propertyName} not found in object {obj.GetType().Name}");
            propertyInfo.SetValue(obj, value);
        }
    }

}